<script setup lang="ts">
import { getGoodsByIdApi } from '@/api/goods'
import { onLoad } from '@dcloudio/uni-app'
import { ref, watchEffect, reactive, computed } from 'vue'
import type { goodsResult, goodsServiceItem } from '@/types/goods'
import type {
  SkuPopupEvent,
  SkuPopupInstance,
  SkuPopupLocaldata,
} from '@/components/vk-data-goods-sku-popup/vk-data-goods-sku-popup'
import { addCartApi } from '@/api/cart'
import { useAddressStore } from '@/stores/modules/address'
import { previewImg, fullUrl, arrayFullUrl, onShowRefreshData } from '@/utils/common'
import { pageUrl, safeBottom } from '@/utils/constants'
import { useCartStore } from '@/stores'
import { postAddFavoriteApi, postCancelFavoriteApi } from '@/api/favorite'
import _, { debounce } from 'lodash'
import { onShareAppMessage } from '@dcloudio/uni-app'
import { useMemberStore } from '@/stores'
import { getAddressApi } from '@/api/address'
import type { addressItem } from '@/types/address'
import { computeConversion } from '@/utils/common'
import servicePanel from '@/pagesGoods/pages/goods/components/servicePanel.vue'
import addressPanel from '@/pagesGoods/pages/goods/components//addressPanel.vue'
import sharePanel from '@/pagesGoods/pages/goods/components/sharePanel.vue'
import sharePoster from '@/pagesGoods/pages/goods/components/sharePoster.vue'

const props = defineProps<{
  id: string | number
  scene?: string
}>()

//接收参数
const query = reactive({
  id: props.id,
  scene: props.scene,
})

const cartStore = useCartStore()

//商品sku弹窗
const isShowSku = ref(false)
//商品sku数据
const skuData = ref({} as SkuPopupLocaldata)
//sku按钮模式
enum skuskuModeType {
  both = 1,
  cart = 2,
  buy = 3,
}
const skuMode = ref<skuskuModeType>(skuskuModeType.both)
//sku弹窗ref实例
const skuPopupRef = ref<SkuPopupInstance>()
//sku中被选中的值
const selectAttrText = computed(() => {
  return skuPopupRef.value?.selectArr?.join(' ').trim() || '请选择商品规格'
})

//打开sku弹窗
const openSkuPopup = (mode: skuskuModeType) => {
  isShowSku.value = true
  skuMode.value = mode
}

const goodsServiceList = ref<goodsServiceItem[]>([])
const goodsServiceText = ref('')
//商品详情
const goods = ref<goodsResult>()
const getGoodsDataById = async () => {
  const res = await getGoodsByIdApi(Number(query.id))
  goods.value = res.result

  //设置sku组件所需数据
  skuData.value = {
    _id: res.result.id.toString(),
    name: res.result.name,
    goods_thumb: fullUrl(res.result.images[0]),
    spec_list: res.result.spec_list.map((spec) => {
      return {
        name: spec.name,
        list: spec.value,
      }
    }),
    sku_list: res.result.sku_list.map((sku) => {
      return {
        _id: sku.id.toString(),
        goods_id: res.result.id.toString(),
        goods_name: res.result.name,
        image: fullUrl(sku.image),
        price: sku.price,
        sku_name_arr: sku.spec?.map((sku_name) => sku_name.value),
        stock: sku.stock,
      }
    }),
  }

  //服务与承诺
  goodsServiceList.value = goods.value.goods_service
  goodsServiceText.value = goods.value.goods_service.map((item) => item.name).join(' ')
}

//更新轮播图下标
const currentIndex = ref(0)
const updateIndex: UniHelper.SwiperOnChange = (event) => {
  currentIndex.value = event.detail.current
}
//弹出层ref
const popup = ref<{
  open: (type?: UniHelper.UniPopupType) => void
  close: () => void
}>()
//调用弹出层
const popupName = ref<'address' | 'service'>()
const openPopup = (name: typeof popupName.value) => {
  popupName.value = name
  popup.value?.open()
}

//添加购物车
const onAddCart = (event: SkuPopupEvent) => {
  addCartApi({
    sku_id: event._id,
    num: event.buy_num,
  }).then((res) => {
    cartStore.setCartTotalNum(res.result.total_num)
    cartInfo.value = res.result.total_num
    isShowSku.value = false
    uni.showToast({
      title: '加入购物车成功',
      icon: 'success',
      mask: true,
    })
  })
}

//跳转下单页
const onBuyNow = (event: SkuPopupEvent) => {
  isShowSku.value = false
  uni.navigateTo({
    url: `${pageUrl['order-create']}?sku_id=${event._id}&count=${event.buy_num}`,
  })
}

// 收货地址
const addressStore = useAddressStore()
const selectAddressText = computed(() => {
  return addressStore.selectedAddress
    ? addressStore.selectedAddress.full_location
    : '请选择收货地址'
})

const addressList = ref<addressItem[]>([])
const openAddressPopup = () => {
  getAddressApi().then((res) => {
    addressList.value = res.result.data
    openPopup('address')
  })
}

const getMoreEvaluate = () => {
  uni.navigateTo({
    url: `${pageUrl['goods-evaluate']}?goods_id=${query.id}`,
  })
}

const cartInfo = ref(0)
const menuButtons = computed<UniHelper.UniGoodsNavOption[]>(() => [
  {
    icon: 'shop',
    text: '首页',
  },
  {
    icon: 'cart',
    text: '购物车',
    info: cartInfo.value,
  },
  {
    icon: 'redo',
    text: '分享',
  },
])
const menuClick = (event: UniHelper.UniGoodsNavOnClickEvent) => {
  switch (event.index) {
    case 0:
      uni.switchTab({
        url: `${pageUrl['index']}`,
      })
      break
    case 1:
      uni.switchTab({
        url: `${pageUrl['cart']}`,
      })
      break
    case 2:
      showSharePopup()
      break
  }
}

const operateButtons: UniHelper.UniGoodsNavButton[] = [
  {
    text: '加入购物车',
    backgroundColor: '#ffa200',
    color: '#fff',
  },
  {
    text: '立即购买',
    backgroundColor: '#ff0000',
    color: '#fff',
  },
]
const buttonClick = (event: UniHelper.UniGoodsNavOnButtonClickEvent) => {
  switch (event.index) {
    case 0:
      openSkuPopup(skuskuModeType.cart)
      break
    case 1:
      openSkuPopup(skuskuModeType.buy)
      break
  }
}

const changeFavoriteStatus = debounce((goods) => {
  if (goods.favorite === true) {
    postCancelFavoriteApi({
      goods_id: goods.id,
    }).then((res) => {
      if (res.result) {
        goods.favorite = false
        uni.showToast({
          title: '商品取消收藏',
          icon: 'none',
        })
      }
    })
  } else {
    postAddFavoriteApi({
      goods_id: goods.id,
    })
      .then((res) => {
        if (res.result) {
          goods.favorite = true
          uni.showToast({
            title: '商品收藏成功',
            icon: 'none',
          })
        }
      })
      .catch((err) => {
        console.log(err)
      })
  }
}, 500)

watchEffect(() => {
  cartInfo.value = useCartStore().cartTotalNum
})

const sharePopupRef = ref()
// 分享弹窗
const showSharePopup = () => {
  if (!useMemberStore().profile?.id) {
    return uni.showModal({
      title: '温馨提示',
      content: '登录解锁更多精彩,是否继续?',
      confirmText: '去登录',
      cancelText: '再看看',
      success: function (res) {
        if (res.confirm) {
          uni.navigateTo({ url: pageUrl['login'] })
        }
      },
    })
  }

  sharePopupRef.value?.open()
}

const sharePosterRef = ref()
const showPoster = ref(false)
const onShowPoster = () => {
  showPoster.value = true

  sharePosterRef.value.open()
}

onShareAppMessage(() => {
  sharePopupRef.value.close()

  const sharePath = `${pageUrl['goods-detail']}?id=${goods.value?.id}&sharer=${
    useMemberStore().profile?.id
  }`
  console.log(sharePath)

  return {
    title: goods.value?.name,
    path: sharePath,
    imageUrl: fullUrl(goods.value!.images[0]),
  }
})

onShowRefreshData(() => {
  if (props.scene) {
    const params = decodeURIComponent(props.scene)
      .split('&')
      .reduce((acc: { [key: string]: any }, curr) => {
        const [key, value] = curr.split('=')
        acc[key] = value
        return acc
      }, {})
    console.log('解析scene', params)
    if (params.id) {
      query.id = params.id
    }
  }

  getGoodsDataById()
})

onLoad(() => {
  // #ifdef MP-WEIXIN
  uni.showShareMenu({
    withShareTicket: true,
    menus: ['shareAppMessage'],
  })
  // #endif
})
</script>

<template>
  <scroll-view scroll-y class="viewport" v-if="goods">
    <!-- 基本信息 -->
    <view class="goods">
      <!-- 商品主图 -->
      <view class="preview">
        <swiper circular @change="updateIndex" autoplay>
          <swiper-item v-for="item in goods?.images" :key="item">
            <image
              class="image"
              :src="fullUrl(item)"
              @tap="previewImg(item, arrayFullUrl(goods!.images))"
            />
          </swiper-item>
        </swiper>
        <view class="indicator">
          <text class="current">{{ currentIndex + 1 }}</text>
          <text class="split">/</text>
          <text class="total">{{ goods?.images.length }}</text>
        </view>
      </view>
    </view>

    <view class="panel">
      <view class="meta">
        <view class="meta-top">
          <view class="price">
            <view class="origin">¥{{ goods.max_origin_price }} </view>
            <view class="current">
              <text class="symbol">¥</text>
              <text class="number">{{ goods?.min_price }}</text>
            </view>
          </view>
          <view class="operate">
            <view class="operate-item" @tap="changeFavoriteStatus(goods!)">
              <view style="display: flex; flex-direction: column" v-if="goods.favorite">
                <text class="icon icon-favorite-checked" />
                <text class="icon-text">已收藏</text>
              </view>
              <view style="display: flex; flex-direction: column" v-else>
                <text class="icon icon-favorite-default" />
                <text class="icon-text">收藏</text>
              </view>
            </view>
            <!-- #ifdef MP-WEIXIN -->
            <view class="contact">
              <button open-type="contact" class="contact-button">
                <text class="icon-handset"></text>
              </button>
              <view class="contact-text">
                <text>客服</text>
              </view>
            </view>
            <!-- #endif -->
          </view>
        </view>
        <view class="name-box">
          <view class="name ellipsis">{{ goods?.name }} </view>
          <view class="sales">
            已售{{ computeConversion(goods.sales_init + goods.sales_real) }}</view
          >
        </view>
      </view>
    </view>

    <view class="panel">
      <view class="action">
        <view class="item arrow" @tap="openSkuPopup(skuskuModeType.both)">
          <text class="label">已选</text>
          <text class="text ellipsis">{{ selectAttrText }}</text>
        </view>
        <view class="item arrow" @tap="openAddressPopup">
          <text class="label">送至</text>
          <text class="text ellipsis">{{ selectAddressText }}</text>
        </view>
        <view class="item arrow" @tap="openPopup('service')">
          <text class="label">服务</text>
          <text class="text ellipsis">{{ goodsServiceText }}</text>
        </view>
      </view>
      <!-- 弹出层 -->
      <uni-popup ref="popup" type="bottom" background-color="#fff">
        <address-panel v-if="popupName === 'address'" @close="popup?.close()" :list="addressList" />
        <service-panel
          v-if="popupName === 'service'"
          :list="goodsServiceList"
          @close="popup?.close()"
        />
      </uni-popup>
    </view>

    <!-- 商品评价 -->
    <view class="panel">
      <view v-if="goods?.evaluate_count > 0" @click="getMoreEvaluate">
        <uni-section :title="`评价 (${computeConversion(goods?.evaluate_count)})`" type="line">
          <template #right>
            <view class="tip">
              <text> 好评率 {{ goods?.positive_rate }}%</text>
              <uni-icons type="forward" size="14" color="#909399" class="icon"></uni-icons>
            </view>
          </template>
          <view class="eva-box" v-for="(evaluate, index) in goods?.evaluate" :key="index">
            <view class="top">
              <shop-user-avatar
                :url="evaluate.user_avatar"
                width="50"
                style="padding-right: 10rpx"
              />
              <text class="name">{{ evaluate.user_name }}</text>
              <view class="rate">
                <uni-rate :value="evaluate.score" :size="20" readonly />
              </view>
            </view>
            <text class="content">{{ evaluate.content }}</text>
            <scroll-view class="scroll-view-container" :scroll-x="true">
              <image
                class="content-img"
                mode="aspectFill"
                v-for="(item, index) in arrayFullUrl(evaluate.images)"
                :key="index"
                :src="item"
                @click.stop="previewImg(item, evaluate.images)"
              />
            </scroll-view>
            <view class="bot"> </view>
          </view>
        </uni-section>
      </view>
      <view v-else>
        <uni-section title="评价 (0)" type="line">
          <z-paging-empty-view empty-view-text="期待您的评价" :empty-view-fixed="false" />
        </uni-section>
      </view>
    </view>

    <view class="panel">
      <uni-section title="详情" type="line">
        <view class="properties">
          <view class="item" v-for="item in goods?.params" :key="item.key">
            <text class="label">{{ item.key }}</text>
            <text class="value">{{ item.value }}</text>
          </view>
        </view>
      </uni-section>
      <view v-if="goods.detail_images.length > 0">
        <shop-image :src="goods?.detail_images" />
      </view>
    </view>

    <view :style="{ paddingBottom: '5rpx' }"> </view>

    <!-- sku弹窗 -->
    <vk-data-goods-sku-popup
      v-model="isShowSku"
      :localdata="skuData"
      :mode="skuMode"
      buy-now-background-color="#ff0000"
      add-cart-background-color="#ffa200"
      :amountType="0"
      ref="skuPopupRef"
      :actived-style="{
        color: '#ff0000',
        backgroundColor: '#fee8e6',
        borderColor: '#ff0000',
      }"
      @add-cart="onAddCart"
      @buy-now="onBuyNow"
      class="sku-popup"
    />

    <uni-popup ref="sharePopupRef" type="bottom" background-color="#fff">
      <share-panel @close="sharePopupRef.close()" @showPoster="onShowPoster" :goods="goods" />
    </uni-popup>

    <sharePoster ref="sharePosterRef" :goods="goods" />
  </scroll-view>

  <!-- 用户操作 -->
  <view class="operate-bar" :style="safeBottom" v-show="goods">
    <uni-goods-nav
      :fill="true"
      :options="menuButtons"
      :buttonGroup="operateButtons"
      @click="menuClick"
      @buttonClick="buttonClick"
    />
  </view>
</template>

<style lang="scss">
swiper {
  height: 100%;
}

page {
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.viewport {
  background-color: #f4f4f4;
  z-index: 999;
}

.panel {
  background-color: #fff;
  border-radius: 10rpx;
  margin: 15rpx 15rpx 20rpx;
  padding: 10rpx;
}

.arrow {
  &::after {
    position: absolute;
    top: 50%;
    right: 30rpx;
    content: '\e6c2';
    color: #ccc;
    font-family: 'iconfont' !important;
    font-size: 32rpx;
    transform: translateY(-50%);
  }
}

/* 商品信息 */
.goods {
  background-color: #fff;
  .preview {
    height: 750rpx;
    position: relative;
    .image {
      width: 750rpx;
      height: 750rpx;
    }
    .indicator {
      height: 40rpx;
      padding: 0 24rpx;
      line-height: 40rpx;
      border-radius: 30rpx;
      color: #fff;
      font-family: Arial, Helvetica, sans-serif;
      background-color: rgba(0, 0, 0, 0.3);
      position: absolute;
      bottom: 30rpx;
      right: 30rpx;
      .current {
        font-size: 26rpx;
      }
      .split {
        font-size: 24rpx;
        margin: 0 1rpx 0 2rpx;
      }
      .total {
        font-size: 24rpx;
      }
    }
  }
}

.meta {
  .meta-top {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
  }

  .operate {
    display: flex;

    .operate-item {
      display: flex;
      flex-direction: column;
      justify-content: center;
      justify-items: center;
      padding-left: 15rpx;
      padding-right: 10rpx;

      .icon {
        text-align: center;
      }

      .icon-text {
        font-size: 20rpx;
        padding-top: 15rpx;
        color: #9a9a9a;
      }

      .icon-favorite-checked {
        color: red;
      }
    }

    .contact {
      button {
        width: 90rpx;
        height: 90rpx;
        background-color: transparent;
      }

      .contact-text {
        font-size: 20rpx;
        text-align: center;
        color: #9a9a9a;
        margin-top: -15rpx;
      }
    }
  }

  .price {
    height: 130rpx;
    padding: 0rpx 20rpx;
    color: red;
    font-size: 34rpx;
    box-sizing: border-box;
    background-color: #fff;
    display: flex;
    flex-direction: column;

    .origin {
      margin-top: 15rpx;
      color: #888;
      text-decoration: line-through;

      ::after {
        content: ￥;
      }
    }
  }
  .number {
    font-size: 50rpx;
  }
  .brand {
    width: 160rpx;
    height: 80rpx;
    overflow: hidden;
    position: absolute;
    top: 26rpx;
    right: 30rpx;
  }
  .name {
    max-height: 88rpx;
    line-height: 1.4;
    margin: 20rpx;
    font-size: 32rpx;
    color: #333;
  }
  .desc {
    line-height: 1;
    padding: 0 20rpx 30rpx;
    font-size: 24rpx;
    color: #cf4444;
  }
  .sales {
    margin: 20rpx;
    font-size: 24rpx;
    color: #888;
  }
}

.action {
  padding-left: 10rpx;
  background: #fff;

  .item {
    height: 90rpx;
    padding-right: 60rpx;
    border-bottom: 1rpx solid #eaeaea;
    font-size: 26rpx;
    color: #333;
    position: relative;
    display: flex;
    align-items: center;
    &:last-child {
      border-bottom: 0 none;
    }
  }
  .label {
    width: 60rpx;
    color: #898b94;
    margin: 0 16rpx 0 10rpx;
  }
  .text {
    flex: 1;
    -webkit-line-clamp: 1;
  }
}

.tip {
  font-size: 24rpx;
  color: #9a9a9a;

  .icon {
    padding-left: 10rpx;
  }
}

.eva-box {
  padding: 10rpx;

  .top {
    display: flex;
    align-items: center;
    padding-bottom: 20rpx;

    .name {
      flex: 1;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      font-size: 26rpx;
      padding-bottom: 10rpx;
    }
  }

  .rate {
    margin-right: 10rpx;
  }

  .content {
    margin: 0rpx 10rpx 10rpx;
    max-height: 100rpx;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    font-size: 24rpx;
  }

  .scroll-view-container {
    width: 100%;
    white-space: nowrap;
    overflow-x: scroll;
    -webkit-overflow-scrolling: touch;

    .content-img {
      margin-left: 10rpx;
      height: 150rpx;
      width: 150rpx;
      margin-bottom: 10rpx;
      margin-right: 10rpx;
      border-radius: 10rpx;
      margin-top: 10rpx;
      scroll-snap-align: start;
    }
  }
}

.properties {
  padding: 0 20rpx;

  .item {
    display: flex;
    line-height: 2;
    padding: 10rpx;
    font-size: 26rpx;
    color: #333;
    border-bottom: 1rpx dashed #ccc;
  }
  .label {
    width: 200rpx;
  }
  .value {
    flex: 1;
  }
}

/* 底部工具栏 */
.toolbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  background-color: #fff;
  height: 100rpx;
  padding: 0 20rpx var(--window-bottom);
  border-top: 1rpx solid #eaeaea;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-sizing: content-box;
  .buttons {
    display: flex;
    & > view {
      width: 220rpx;
      text-align: center;
      line-height: 72rpx;
      font-size: 26rpx;
      color: #fff;
      border-radius: 72rpx;
    }
    .addcart {
      background-color: #ffa868;
    }
    .buynow,
    .payment {
      background-color: #ff5f3c;
      margin-left: 20rpx;
    }
  }
  .icons {
    padding-right: 10rpx;
    display: flex;
    align-items: center;
    flex: 1;
    .icons-button {
      flex: 1;
      text-align: center;
      line-height: 1.4;
      padding: 0;
      margin: 0;
      border-radius: 0;
      font-size: 20rpx;
      color: #333;
      background-color: #fff;
      &::after {
        border: none;
      }
    }
    text {
      display: block;
      font-size: 34rpx;
    }
  }
}
</style>
